<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise</title>
</head>

<body>
    <script>
        // 所谓Promise，简单说就是一个容器，里面保存着某个未来才会结束的事件（通常是一个异步操作）的结果。从语法上说，Promise 是一个对象，从它可以获取异步操作的消息。Promise 提供统一的 API，各种异步操作都可以用同样的方法进行处理。
        // Promise 对象有以下两个特点
        // 1、对象的状态不受外界影响
        // 2、一旦状态改变 就不会再变 ，任何时候都可以得到这个结果

        // 基本用法 Promise 对象是一个构造函数

        const promise = new Promise((resolve, reject) => {
            // if (true) { // 异步操作成功
            //     //
            //     resolve(res)
            // } else {
            //     //
            //     reject(error)
            // }
        })

        promise.then(function (value) {
            // success
        }, function (error) {
            //failure
        })
        // then 方法接受两个参数，一个是回调函数是Promise 对象的状态变为resolved 时调用，第二个回调函数是Promise 对象的状态变为rejected 时调用。这两个函数都是可选的，不一定要提供，它们都接受Promise 对象传出的值作为参数。

        function timeout(ms) {
            return new Promise((resolve, reject) => {
                setTimeout(resolve, ms, 'donedonedonedonedone')
            })
        }
        timeout(100).then(value => {
            console.log(value)
        })

        let promise2 = new Promise((resolve, reject) => {
            console.log('promise2')
            resolve('value vaule222')
        })
        promise2.then(value => {
            console.log("resolve::", value)
        })
        console.log("HI")


        // 异步加载图片的案例
        function loadImageAsync(url) {
            return new Promise((resolve, reject) => {
                const image = new Image();
                // image.onload = (() => resolve(image))
                image.onload = (resolve(image))

                image.onerror = function () {
                    reject(new Error('Could not load image at ' + url))
                }

                image.src = url
            })
        }

        loadImageAsync(
            'https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3363295869,2467511306&fm=26&gp=0.jpg').then(
            (image) => {
                console.log("iamge", image)
            }).catch(error => {
            console.log('error', error)
        })


        const p1 = new Promise(function (resolve, reject) {
            setTimeout(() => reject(new Error('fail')), 3000)
        })

        const p2 = new Promise(function (resolve, reject) {
            setTimeout(() => resolve(p1), 1000)
        })

        p2
            .then(result => console.log("result:::", result))
            .catch(error => console.log(error))
        // Error: fail

        // 上面代码中，p1是一个 Promise，3 秒之后变为rejected。p2的状态在 1 秒之后改变，resolve方法返回的是p1。由于p2返回的是另一个 Promise，导致p2自己的状态无效了，由p1的状态决定p2的状态。所以，后面的then语句都变成针对后者（p1）。又过了 2 秒，p1变为rejected，导致触发catch方法指定的回调函数。

        // 注意，调用resolve或reject并不会终结 Promise 的参数函数的执行。

        // 一般来说，调用resolve或reject以后，Promise 的使命就完成了，后继操作应该放到then方法里面，而不应该直接写在resolve或reject的后面。所以，最好在它们前面加上return语句，这样就不会有意外。

        // 6 、Promise.all() 方法用于经多个Promise实例，包装秤一个新的Promise 实例
        const pall = Promise.all([p1, p2])
    </script>
</body>

</html>